import { _decorator, Component, Node, Label, Graphics, Vec2, Color, UITransform, Vec3, tween, Camera } from 'cc';
import { Global, GuideTipData } from '../../Util/Global';
import GameEventMgr, { GameEvent } from '../../Model/GameEventMgr';
import { UICtrl } from '../../Ctrl/UICtrl';
import { Unit } from '../Unit';

const { ccclass, property, requireComponent } = _decorator;

@ccclass('GuideTip')
@requireComponent(Graphics)
export class GuideTip extends Component {
    graphics: Graphics = null;
    @property(Label)
    messageLabel: Label = null;
    @property(Node)
    left: Node = null;
    @property(Node)
    right: Node = null;

    data: GuideTipData = null;
    uiTran: UITransform = null;

    private selfTran: UITransform = null;
    private targetTran: UITransform = null;

    private target_world_pos: Vec3 = new Vec3();
    private target_lcoal_pos: Vec3 = new Vec3();
    private self_world_pos: Vec3 = new Vec3();
    private self_local_pos: Vec3 = new Vec3();

    private offset: Vec3 = new Vec3;


    private _isShow: boolean = true;
    set Showing(val: boolean) {
        if (this._isShow != val && val) {
            this.schedule(this.TickShowMessage, this.data.animInterval || 0.02);
        }
        else if (!val) {
            this.unschedule(this.TickShowMessage);
        }
        this._isShow = val;
    }
    get Showing() {
        return this._isShow;
    }

    private _onDestroy() {
        this._nextGuide = null;
        this.node.destroy();
    }

    start() {

        GameEventMgr.Register(this, GameEvent.OnClickBackHome, this._onDestroy.bind(this));
        GameEventMgr.Register(this, GameEvent.GameReset, this._onDestroy.bind(this));
        this.graphics = this.getComponent(Graphics);
        this.selfTran = this.getComponent(UITransform);
        this.targetTran = this.data.target.getComponent(UITransform);

        if (this.data.offset) {
            this.offset = this.data.offset;
        }
        if (this.data.fontSize) {
            this.messageLabel.fontSize = this.data.fontSize;
            this.messageLabel.lineHeight = this.data.fontSize;
        }
        this.messageLabel.string = '';
        this.messageLabel.getComponent(UITransform).anchorX = this.offset.x > 0 ? 0 : 1;

        if (this._isShow) {
            this.schedule(this.TickShowMessage, this.data.animInterval || 0.02);
        }
        //在View层级先更新下位置
        if (this.data.target != this.node.parent && this.uiTran) {
            // this.data.target.getWorldPosition(this.target_world_pos);
            // this.self_world_pos.x = this.target_world_pos.x + this.offset.x;
            // this.self_world_pos.y = this.target_world_pos.y + this.offset.y;

            // this.uiTran.convertToNodeSpaceAR(this.self_world_pos, this.self_local_pos);

            this.ui_to_view_pos();
            let pos = this.offset.clone().add(this.target_lcoal_pos);
            this.node.setPosition(pos);
        }
    }
    //target在ui层上
    private ui_to_view_pos() {
        this.data.target.getWorldPosition(this.target_world_pos);
        let uiCamera = UICtrl.Instance.uiGraphicsTran.getComponentInChildren(Camera);
        let viewCamera = UICtrl.Instance.viewGraphicsTran.getComponentInChildren(Camera);
        uiCamera.worldToScreen(this.target_world_pos, this.target_world_pos)
        viewCamera.screenToWorld(this.target_world_pos, this.target_world_pos)
        this.selfTran.convertToNodeSpaceAR(this.target_world_pos, this.target_lcoal_pos)
    }

    private _nextGuide: GuideTip = null;
    NextGuideOnDestroy(data: GuideTipData) {

        this._nextGuide = UICtrl.CreateGuideMessageOnGameScene(data);
        this._nextGuide.Showing = false;
        return this._nextGuide;
    }

    protected onDestroy(): void {
        if (this._nextGuide && !Global.gameManager.gameover) {
            this._nextGuide.Showing = true;
        }
    }

    protected onDisable(): void {
        if (this.node.activeInHierarchy) {
            this.node.destroy();
        }
    }

    update(deltaTime: number) {
        if (!this.data || !this._isShow) {
            return
        }
        if (this.data.target) {
            if (!this.data.target.active) {
                this.node.destroy();
            }
            if (this.data.target == this.node.parent) {
                this.FollowLineRenderer(this.data.GuideLineColor || Color.WHITE);
            }
            else if (this.uiTran) {
                this.FixedLineRenderer(this.data.GuideLineColor || Color.WHITE);
            }
        }
        if (this.data.lifeCondition && !this.data.lifeCondition()) {
            this.node.destroy();
        }
    }

    private currentShowIndex: number = 0;
    TickShowMessage() {
        if (this.currentShowIndex < this.data.message.length) {
            this.messageLabel.string += this.data.message[this.currentShowIndex];  // 添加下一个字符
            this.currentShowIndex++;  // 索引加一
        } else {
            // console.log(this.messageLabel.string)
            this.unschedule(this.TickShowMessage);  // 取消定时任务

            if (this.data.lifeTime && this.data.lifeTime > 0 && this.data.lifeCondition == null) {
                tween(this.node).delay(this.data.lifeTime).call(() => {
                    this.node.destroy();
                }).start();
            }
        }
    }

    private text_forward: Vec2 = new Vec2(0, 1);//文字朝向
    private target_toward: Vec3 = new Vec3;//目标在世界坐标下的朝向
    private target_toward_v2: Vec2 = new Vec2;
    /**跟踪绘制，请确保target是tip的父级 */
    FollowLineRenderer(color: Color): void {

        let updateTextLookAtUp = () => {
            let target_forward_pos = this.targetTran.convertToWorldSpaceAR(Vec3.UP.clone());
            this.data.target.getWorldPosition(this.target_world_pos);
            this.target_toward = target_forward_pos.subtract(this.target_world_pos);
            this.target_toward_v2.set(this.target_toward.x, this.target_toward.y);
            let angle = this.text_forward.signAngle(this.target_toward_v2) * 180 / Math.PI;
            this.node.setRotationFromEuler(0, 0, -angle);//设置文字保持水平
        }

        let unit = this.data.target.getComponent(Unit)
        if (unit) {
            updateTextLookAtUp();
        }

        let graphics = this.graphics;
        graphics.clear();

        // 设置直线的样式
        graphics.lineWidth = this.data.GuideLineSize || 2; // 线宽
        graphics.strokeColor = color; // 线条颜色
        graphics.lineCap = 1;

        // 绘制
        if (this.offset.x > 0) {
            let pos = this.left.position;
            graphics.moveTo(pos.x, pos.y);
        }
        else {
            let pos = this.right.position;
            graphics.moveTo(pos.x, pos.y);
        }

        this.data.target.getWorldPosition(this.target_world_pos);
        this.selfTran.convertToNodeSpaceAR(this.target_world_pos, this.target_lcoal_pos)
        if (unit) {
            this.self_world_pos.x = this.target_world_pos.x + this.offset.x;
            this.self_world_pos.y = this.target_world_pos.y + this.offset.y;
            //从世界坐标转本地，以免收到单位旋转的影响
            this.targetTran.convertToNodeSpaceAR(this.self_world_pos, this.self_local_pos);
            this.node.setPosition(this.self_local_pos);
        }
        else {
            this.node.setPosition(this.offset);
        }

        graphics.lineTo(this.target_lcoal_pos.x, this.target_lcoal_pos.y);
        graphics.stroke();//在当前tran画

        graphics.moveTo(this.left.position.x, this.left.position.y);
        graphics.lineTo(this.right.position.x, this.right.position.y);
        graphics.stroke();
    }

    /**
     * View层绘制，固定位置，target在UI层
     */
    FixedLineRenderer(color: Color) {
        let graphics = this.graphics;
        graphics.clear();

        // 设置直线的样式
        graphics.lineWidth = this.data.GuideLineSize || 2; // 线宽
        graphics.strokeColor = color; // 线条颜色

        if (this.offset.x > 0) {
            let pos = this.left.position;
            graphics.moveTo(pos.x, pos.y);
        }
        else {
            let pos = this.right.position;
            graphics.moveTo(pos.x, pos.y);
        }

        this.ui_to_view_pos();
        this.selfTran.convertToNodeSpaceAR(this.target_world_pos, this.target_lcoal_pos)
        //     .convertToUINode(this.target_world_pos,this.selfTran.node,this.target_lcoal_pos);
        graphics.lineTo(this.target_lcoal_pos.x, this.target_lcoal_pos.y);

        graphics.stroke();

        graphics.moveTo(this.left.position.x, this.left.position.y);
        graphics.lineTo(this.right.position.x, this.right.position.y);
        graphics.stroke();
    }
}


